home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XA_6S.ZIP / SOURCE / FSELECT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-15  |  9.5 KB  |  416 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <OSBIND.H>
  9. #include <MINTBIND.H>
  10. #include <SIGNAL.H>
  11. #include <FILESYS.H>
  12. #include <VDI.H>
  13. #include <unistd.h>            /* getcwd() */
  14. #include <stdlib.h>            /* free() */
  15. #include <string.h>
  16. #include <limits.h>            /* PATH/NAME_MAX */
  17. #include "entries.h"            /* directory entry stuff */
  18. #include "XA_TYPES.H"
  19. #include "XA_CODES.H"
  20. #include "XA_DEFS.H"
  21. #include "XA_GLOBL.H"
  22. #include "OBJECTS.H"
  23. #include "FRM_ALRT.H"
  24. #include "STD_WIDG.H"
  25. #include "C_WINDOW.H"
  26. #include "RECTLIST.H"
  27. #include "SYSTEM.H"
  28. #include "RESOURCE.H"
  29. #include "SCRLOBJC.H"
  30. #include "K_DEFS.H"
  31. #include "graf_mou.h"
  32.  
  33. /*
  34.     FILE SELECTOR IMPLEMENTATION
  35.     
  36.     This give a non-modal windowed file selector for internal
  37.     and exported use, with slightly extended pattern matching
  38.     from the basic GEM spec.
  39. */
  40.  
  41. short fs_destructor(XA_WINDOW *wind);
  42.  
  43. XA_WINDOW *fs_open=NULL;
  44. FileSelectedCallback selected=NULL;
  45. FileSelectedCallback cancelled=NULL;
  46. char fs_path[PATH_MAX];
  47. char fs_pattern[NAME_MAX*2];
  48. char fs_internal_filter[NAME_MAX*2];
  49. char fs_internal_file[NAME_MAX];
  50.  
  51.  
  52. /*
  53.     Re-load a file list object
  54. */
  55. void refresh_filelist(void)
  56. {
  57.     Entry *first;
  58.     Lists *lists;
  59.     char **dirs, **files;
  60.     OBJECT *form=ResourceTree(system_resources,FILE_SELECT);
  61.     OBJECT *sl,*temp;
  62.     SCROLL_INFO *si;
  63.     SCROLL_ENTRY *entry;
  64.  
  65.     DIAGS(("refresh_filelist:fs_path='%s',fs_pattern='%s'\n",fs_path,fs_pattern));
  66.     sl=form+FS_LIST;
  67.     si=(SCROLL_INFO*)sl->ob_spec;
  68.  
  69.     if (fs_open)                    /* Clear out current file list contents */
  70.     {
  71.         free(si->scrl_start);
  72.         free_entries();
  73.     }
  74.  
  75.     graf_mouse(HOURGLASS,NULL);
  76.     
  77.     first = read_entries(fs_path);        /* Read new directory */
  78.  
  79.     DIAGS(("entries have been read:first=\n",first));
  80.  
  81.     if(!(lists = sort_entries(fs_pattern)))    /* Sort directory */
  82.     {
  83.         graf_mouse(ARROW,NULL);
  84.         return;
  85.     }
  86.     
  87.     si->scrl_start=(SCROLL_ENTRY*)malloc(sizeof(SCROLL_ENTRY)*(lists->num_dirs+lists->num_files));
  88.     entry=si->scrl_start;
  89.  
  90.     temp=form+FS_ICN_DIR;
  91.     temp->ob_x=temp->ob_y=0; temp->ob_flags|=HIDETREE;
  92.     temp=form+FS_ICN_EXE;
  93.     temp->ob_x=temp->ob_y=0; temp->ob_flags|=HIDETREE;
  94.  
  95.     DIAGS(("entries have been sorted\n"));
  96.     
  97.     DIAGS(("DIRS:\n"));
  98.     
  99.     dirs = lists->dirs;
  100.     while(*dirs)                    /* Stick directorys at top of list */
  101.     {
  102.         entry->icon=form+FS_ICN_DIR;
  103.         entry->text=*(dirs++);
  104.         DIAGS(("%s\n",entry->text));
  105.         entry->next=entry+1;
  106.         entry->prev=entry-1;
  107.         entry++;
  108.     }
  109.  
  110.     DIAGS(("FILES:\n"));
  111.  
  112.     files = lists->files;
  113.     while(*files)                    /* Add files after directorys */
  114.     {
  115.         entry->text=*files;
  116.         if (((Entry *)*files - 1)->flags&FLAG_EXECUTABLE)
  117.         {
  118.             entry->icon=form+FS_ICN_EXE;
  119.         }else{
  120.             entry->icon=NULL;
  121.         }
  122.         DIAGS(("%s\n",entry->text));
  123.         entry->next=entry+1;
  124.         entry->prev=entry-1;
  125.         files++;
  126.         entry++;
  127.     }
  128.     si->scrl_start->prev=NULL;
  129.     (--entry)->next=NULL;
  130.     
  131.     si->scrl_dstart=si->scrl_current=si->scrl_start;
  132.  
  133.     graf_mouse(ARROW,NULL);
  134.     
  135. }
  136.  
  137. static char null_file[]="NONAME.XXX";
  138.  
  139. short __stdargs fs_click(OBJECT *form, short objc)
  140. {
  141.     SCROLL_INFO *list;
  142.     OBJECT *ob=form+objc;
  143.     char *current_filename;
  144.     Entry *current_entry;
  145.         
  146.     list=(SCROLL_INFO*)ob->ob_spec;
  147.     
  148.     if (list->scrl_current)
  149.     {
  150.         current_filename=list->scrl_current->text;
  151.         current_entry=(Entry *)current_filename - 1;
  152.  
  153.         if (!(current_entry->flags & FLAG_DIR))
  154.         {
  155.             strcpy(fs_internal_file,current_filename);
  156.             v_hide_c(V_handle);
  157.             draw_object_tree(form, FS_FILE, 1);
  158.             v_show_c(V_handle,1);
  159.         }
  160.     }
  161.     
  162.     return TRUE;
  163. }            
  164.  
  165.     
  166. short __stdargs fs_dclick(OBJECT *form, short objc)
  167. {
  168.     SCROLL_INFO *list;
  169.     OBJECT *ob=form+objc;
  170.     char *current_filename;
  171.     Entry *current_entry;
  172.     XA_WINDOW *wl;
  173.     GRECT r;
  174.         
  175.     list=(SCROLL_INFO*)ob->ob_spec;
  176.  
  177.     if (list->scrl_current)
  178.     {
  179.         current_filename=list->scrl_current->text;
  180.         current_entry=(Entry *)current_filename - 1;
  181.  
  182.         if (current_entry->flags & FLAG_DIR)
  183.         {            
  184.             if (current_filename[0]!='.')
  185.             {
  186.                 if (fs_path[strlen(fs_path)-1]!='/')        
  187.                     strcat(fs_path,"/");
  188.                 strcat(fs_path,current_filename);
  189.                 refresh_filelist();
  190.                 v_hide_c(V_handle);
  191.                 draw_object_tree(form, FS_LIST, 1);
  192.                 v_show_c(V_handle,1);
  193.             }else{
  194.                 if (current_filename[1]=='.')
  195.                 {
  196.                     short s,l=strlen(fs_path);
  197.                     s=l; 
  198.                     while(fs_path[--s]!='/');
  199.                     if (s>2)
  200.                     {
  201.                         fs_path[s]='\0';
  202.                     }else{
  203.                         fs_path[3]='\0';
  204.                     }
  205.                     refresh_filelist();
  206.                     v_hide_c(V_handle);
  207.                     draw_object_tree(form, FS_LIST, 1);
  208.                     v_show_c(V_handle,1);
  209.                 }
  210.             }
  211.             
  212.             return TRUE;
  213.             
  214.         }
  215.         
  216.         if (selected)
  217.                 (*selected)(fs_path,fs_internal_file);
  218.                 
  219.     }else{
  220.         if (selected)
  221.             (*selected)(fs_path,null_file);
  222.     }
  223.  
  224.     wl=fs_open->next;
  225.     
  226.     r.g_x=fs_open->x;    r.g_y=fs_open->y;
  227.     r.g_w=fs_open->w;    r.g_h=fs_open->h;
  228.  
  229.     fs_open->is_open=FALSE;
  230.     send_wind_to_bottom(fs_open);
  231.     delete_window(fs_open);
  232.  
  233.     v_hide_c(V_handle);
  234.     display_windows_below(&r,wl);
  235.     v_show_c(V_handle,1);
  236.             
  237.     return TRUE;
  238. }
  239.  
  240. void handle_fileselector(ODC_PARM *odc_p)
  241. {
  242.     short s,l=strlen(fs_path);
  243.     TEDINFO *filter=(TEDINFO*)(odc_p->tree+FS_FILTER)->ob_spec;
  244.     GRECT r;
  245.     XA_WINDOW *wl;
  246.     
  247.     switch(odc_p->object)
  248.     {
  249.         case FS_UPDIR:            /* Go up a level in the filesystem */
  250.             s=l=strlen(fs_path);
  251.             while(fs_path[--s]!='/');
  252.             if (s>2)
  253.             {
  254.                 fs_path[s]='\0';
  255.             }else{
  256.                 fs_path[3]='\0';
  257.             }
  258.             refresh_filelist();
  259.             v_hide_c(V_handle);
  260.             draw_object_tree(odc_p->tree, FS_LIST, 1);
  261.             v_show_c(V_handle,1);
  262.             break;
  263.         case FS_OK:                            /* Accept current selection - do the same as a double click */
  264.             if (strcmp(filter->te_ptext,fs_pattern))
  265.             {
  266.                 strcpy(fs_pattern,filter->te_ptext);
  267.                 refresh_filelist();
  268.                 v_hide_c(V_handle);
  269.                 draw_object_tree(odc_p->tree, FS_LIST, 1);
  270.                 v_show_c(V_handle,1);
  271.             }else{
  272.                 fs_dclick(odc_p->tree,FS_LIST);
  273.             }
  274.             break;
  275.         case FS_CANCEL:                    /* Cancel this selector */
  276.             if (cancelled)
  277.                 (*cancelled)(fs_path,"");
  278.  
  279.             wl=fs_open->next;
  280.             r.g_x=fs_open->x;    r.g_y=fs_open->y;
  281.             r.g_w=fs_open->w;    r.g_h=fs_open->h;
  282.  
  283.             fs_open->is_open=FALSE;
  284.             send_wind_to_bottom(fs_open);
  285.             delete_window(fs_open);
  286.  
  287.             v_hide_c(V_handle);
  288.             display_windows_below(&r,wl);
  289.             v_show_c(V_handle,1);
  290.             break;
  291.     }
  292. }
  293.  
  294. void open_fileselector(char *path, char *title, FileSelectedCallback s, FileSelectedCallback c)
  295. {
  296.     SCROLL_INFO *list;
  297.     OBJECT *form=ResourceTree(system_resources,FILE_SELECT);
  298.     TEDINFO *filter;
  299.     XA_WINDOW *dialog_window;
  300.     XA_WIDGET_LOCATION dialog_toolbar_loc={LT,3,0};
  301.     XA_WIDGET_LOCATION dialog_menu_loc={LT,16,0};
  302.     short x,y,w,h;
  303.     char *pat;
  304.  
  305.     DIAGS(("open_fileselector(%s,%s,%lx)\n",path,title,s));
  306.     
  307.     if (fs_open)
  308.         return;
  309.     
  310.     selected=s;
  311.     cancelled=c;
  312.         
  313.     dialog_menu_loc.y=display.c_max_h+1;
  314.     dialog_toolbar_loc.y=dialog_menu_loc.y+display.c_max_h+1;
  315.  
  316.     filter=(TEDINFO*)(form+FS_FILTER)->ob_spec;
  317.     filter->te_ptext=fs_internal_filter;
  318.     filter->te_txtlen=NAME_MAX*2;
  319.     ((TEDINFO*)(form+FS_FILE)->ob_spec)->te_ptext=fs_internal_file;
  320.     
  321.     form->ob_x=(display.w-form->ob_width)/2;
  322.     form->ob_y=(display.h-form->ob_height)/2;
  323.  
  324.     strcpy(fs_path,path);
  325.  
  326. /* Strip out the pattern description */
  327.     for(pat=fs_path+strlen(fs_path); (pat>fs_path)&&(*pat!='/'); pat--);
  328.     if (pat>fs_path)
  329.     {
  330.         *pat++='\0';
  331.         strcpy(fs_pattern,pat);
  332.     }else{
  333.         fs_pattern[0]='*';
  334.         fs_pattern[1]='\0';
  335.     }
  336.  
  337.     fs_internal_file[0]='\0';
  338.     
  339.     refresh_filelist();
  340.  
  341.     DIAGS(("Refreshed file list\n"));
  342.  
  343. /* Create a temporary window to work out sizing */
  344.     dialog_window=create_window(AESpid, NAME|MOVE, form->ob_x, form->ob_y, form->ob_width, form->ob_height);
  345.  
  346.     x=2*dialog_window->x - dialog_window->wx;
  347.     y=2*dialog_window->y - dialog_window->wy;
  348.     w=2*dialog_window->w - dialog_window->ww +1;
  349.     h=2*dialog_window->h - dialog_window->wh +1;
  350.  
  351. /* Dispose of the temporary window we created */
  352.     delete_window(dialog_window);
  353.  
  354. /* Now create the real window */
  355.     dialog_window=create_window(AESpid, NAME|MOVE|NO_MESSAGES|NO_WORK, x, y, w, h);
  356.  
  357.     dialog_window->created_by_FMD_START=FALSE;
  358.  
  359. /* Set the window title */
  360.     dialog_window->widgets[XAW_TITLE].stuff=title;
  361.     
  362. /* Set the window destructor */
  363.     dialog_window->destructor=&fs_destructor;
  364.  
  365. /* Set the menu widget */
  366. #if 0
  367.     set_menu_widget(dialog_window, dialog_menu_loc, (OBJECT*)ResourceTree(system_resources, FSEL_MENU));
  368. #endif
  369.  
  370. /* Set the main dialog widget */
  371.     dialog_toolbar_loc.y=display.c_max_h+10;
  372.     set_toolbar_widget(dialog_window, dialog_toolbar_loc, form);
  373.     
  374.     list=(SCROLL_INFO*)(form+FS_LIST)->ob_spec;
  375.     list->scrl_f_dclick=&fs_dclick;                    /* Set the scroll lists double click callback */
  376.     list->scrl_f_click=&fs_click;                    /* Set the scroll lists click callback */
  377.     
  378.     list->scrl_title=fs_path;
  379.     
  380.     ((XA_WIDGET_TREE*)dialog_window->widgets[XAW_TOOLBAR].stuff)->owner=AESpid;
  381.     ((XA_WIDGET_TREE*)dialog_window->widgets[XAW_TOOLBAR].stuff)->handler=&handle_fileselector;
  382.  
  383.     strcpy(fs_internal_filter,fs_pattern);
  384.     
  385.     dialog_window->is_open=TRUE;
  386.  
  387.     v_hide_c(V_handle);
  388.     pull_wind_to_top(dialog_window);
  389.     DIAGS(("calling display_window()\n"));
  390.     display_window(dialog_window);
  391.     v_show_c(V_handle,1);
  392.     
  393.     DIAGS(("done.\n"));
  394.     
  395.     fs_open=dialog_window;
  396.  
  397. }
  398.  
  399. short fs_destructor(XA_WINDOW *wind)
  400. {
  401.     OBJECT *form=ResourceTree(system_resources,FILE_SELECT);
  402.     OBJECT *sl;
  403.     SCROLL_INFO *si;
  404.  
  405.     sl=form+FS_LIST;
  406.     si=(SCROLL_INFO*)sl->ob_spec;
  407.     
  408.     free(si->scrl_start);
  409.     si->scrl_start=si->scrl_current=si->scrl_dstart=NULL;
  410.     free_entries();
  411.     fs_open=NULL;
  412.     selected=NULL;
  413.     
  414.     return TRUE;
  415. }
  416.